import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.*;
import java.util.zip.*;
import java.io.*;

/**
 * 验证从EP解密出的密钥是否能解密data
 */
public class VerifyEPKey {
    
    // 从加密数据.md获取
    private static final String DATA_BASE64 = "wHBy2LDIay6WCgEybO8bw/5OxmVd4N++OJpwr/Tgjw+TA8iZ4HAy4bN8UWtwmeGz+dqU/zX6myCireq+q465rqUqpXLhma2aEPqTaNvUTv/Y71kVpkMBkgrjMnVkIi/iBV5eKsrTPfLWO8bt0mSbLM8ghswC2m2YRInkqWXHrc8Nw0JsNjwCllOUdtwe3NuIx8oQuQ2fqj1G3g3xMp6B4sWBNAo+SjTNuKnS4chvbaD3RYnGvSLyNYu+sqbKeRNofCwVn0lVrjCAGtC9d5nqhFiGw0vWksPfmCRn7vRsl7LnqcXb+Fal/hhREBsaRJdMrst3vOEeQI6pt3RGKZ3VOsliNziKbLiNnXp2zY2fin32okAFwIOczPgeQA1yAM4FCnuT9FYAMn5ecAOY7WFhJPcOqVThy0giCJrBzpIzEHXTin+BWBO1PR8wMzBqpf6us9mhBZGzu40mzVN34xXK646aMr8f2DcD9yGO20v5icEz3OUcAeayMq+YKmBoypmvQUnaGa8pjr7RfvvajY+7pu6QHqRAQ3NLY1KjIoT3PKjabb7owQ1Txw5+Ajfjen7VEeF/Dq03nPMtNOpqD3tCdWDHWir+akJcEPtPzK4Bo2K3FrLBZt2igZD6/04jtwoAojHibKqUM1Rj5h2iijH65eAU1XKTpqDPNtcP5lwa1bFNV+GvuzHM+N4gcoxiELhQeG7xiUcsZrJvadkDO2z+If9vLkXTSdMKrqozUjLRapyXpULcVL8negHnj+2vKZVdoGiDhXlm23XDFjLY91ZqX2eGfGNmpJxftl83N6q4dyXpzD2gR/chHfm0CukVlL8P8aPAfEDcAsyQETc5oVLzetGVSkGBbQl+axZu8U2Ap9CXaTi1b2VcI3he19nvgG8XEFnwP6Tbicm5PDDsiRjo2MRqfuPLWkcSHTmBlS6w8yrzAvth9x/bBLg8XLs8M/B/dKSfOa9sbptfTMmEuuhWbnqCyqnFSUt8lsFlcUbJdK02TcMbd789pANnrKTTfFeOUehu5XReHng4DfV7f6boQmJPnZfwuR8qFwp7vwme235RTloktlkQu/2QFl2LmCv+/8Za43dEdFba9Ae6I1p+50zunyIjGTE6/9RT+g/zgagzgV/qDDSM5VF6E2Ic62W/KkpfSPMHAk5Jwg0LlsSMnFXYCynZoDZ5M8s62V15VaEII3s/6wPCu4lba/BxPanRtw60EVsvrJ7B0mnG+hcW8AGVeG1ZBIhgPH887/bY+05b0MnSkhjlrys8GKSaukVbtnrLJmjePt+LdLe6tH2NTwxjbHhJR028ZWaQKvdC5BD2hRflDMBPKL68D6YJ2bitqnKKdEqYHdCMXtOXh68XUqwfkoF3phQtYHyrqF4Wsgukf3/gAlt/yF0dXFTIUzoDTc34MEAaLFENVFDt4PUnYw2SRT8i/bhi3tcavu6Hnjs=";
    
    // EP解密后得到的数据 (从NoPadding解密结果)
    // 注意: 第一个字节是0x00填充，真正的密钥从字节[1:33]
    private static final String EP_KEY_HEX = "d18b48d47c664dc697ae620dc463ac556ce657ce57f45bc4e46177ad751db597";
    private static final String EP_IV_HEX = "7e30aa747fc71c70ebc302493eeb86e0";
    
    public static void main(String[] args) {
        System.out.println("\n" + "=".repeat(80));
        System.out.println("              验证 EP 解密出的密钥是否正确");
        System.out.println("=".repeat(80) + "\n");
        
        try {
            byte[] dataEncrypted = Base64.getDecoder().decode(DATA_BASE64);
            System.out.println("data 加密长度: " + dataEncrypted.length + " 字节");
            
            // 从EP解密结果中提取的密钥和IV
            byte[] key = hexToBytes(EP_KEY_HEX);
            byte[] iv = hexToBytes(EP_IV_HEX);
            
            System.out.println("EP密钥长度: " + key.length + " 字节");
            System.out.println("EP IV长度: " + iv.length + " 字节");
            
            System.out.println("\n" + "-".repeat(80));
            System.out.println("测试1: 使用EP密钥和IV，前16字节作为IV");
            System.out.println("-".repeat(80));
            
            testDecrypt(dataEncrypted, key, iv);
            
            System.out.println("\n" + "-".repeat(80));
            System.out.println("测试2: 使用data前16字节作为IV");
            System.out.println("-".repeat(80));
            
            byte[] dataIV = Arrays.copyOfRange(dataEncrypted, 0, 16);
            byte[] dataCiphertext = Arrays.copyOfRange(dataEncrypted, 16, dataEncrypted.length);
            System.out.println("data自带IV: " + bytesToHex(dataIV));
            System.out.println("data密文长度: " + dataCiphertext.length + " 字节");
            
            testDecrypt(dataCiphertext, key, dataIV);
            
            System.out.println("\n" + "-".repeat(80));
            System.out.println("测试3: 整个data作为密文，使用EP的IV");
            System.out.println("-".repeat(80));
            
            testDecrypt(dataEncrypted, key, iv);
            
        } catch (Exception e) {
            System.err.println("❌ 错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    private static void testDecrypt(byte[] ciphertext, byte[] key, byte[] iv) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(iv);
            
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] decrypted = cipher.doFinal(ciphertext);
            
            System.out.println("✅ AES解密成功！");
            System.out.println("解密长度: " + decrypted.length + " 字节");
            
            // 尝试zlib解压
            System.out.println("\n尝试zlib解压...");
            try {
                byte[] decompressed = zlibDecompress(decrypted);
                System.out.println("✅ zlib解压成功！");
                System.out.println("解压长度: " + decompressed.length + " 字节");
                
                // 尝试解析为JSON
                String json = new String(decompressed, "UTF-8");
                System.out.println("\n🎉🎉🎉 成功解密data！内容如下:");
                System.out.println("=".repeat(80));
                System.out.println(json);
                System.out.println("=".repeat(80));
                
            } catch (Exception e) {
                System.out.println("❌ zlib解压失败: " + e.getMessage());
                System.out.println("\n解密后的原始数据(前256字节HEX):");
                System.out.println(bytesToHex(Arrays.copyOfRange(decrypted, 0, Math.min(256, decrypted.length))));
                
                System.out.println("\n尝试解析为UTF-8:");
                try {
                    String text = new String(decrypted, "UTF-8");
                    System.out.println(text.substring(0, Math.min(200, text.length())));
                } catch (Exception ex) {
                    System.out.println("(无法解析为文本)");
                }
            }
            
        } catch (javax.crypto.BadPaddingException e) {
            System.out.println("❌ 解密失败: 填充错误 (密钥或IV不正确)");
        } catch (Exception e) {
            System.out.println("❌ 解密失败: " + e.getMessage());
        }
    }
    
    private static byte[] zlibDecompress(byte[] data) throws Exception {
        Inflater inflater = new Inflater();
        inflater.setInput(data);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
        byte[] buffer = new byte[1024];
        while (!inflater.finished()) {
            int count = inflater.inflate(buffer);
            outputStream.write(buffer, 0, count);
        }
        outputStream.close();
        return outputStream.toByteArray();
    }
    
    private static byte[] hexToBytes(String hex) {
        int len = hex.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return data;
    }
    
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}



